<!DOCTYPE html>
<html>
<head>
    <title>v6</title>
    <script>
        // Compatibility hack
        if (window.WebKitBlobBuilder)
            window.BlobBuilder = window.WebKitBlobBuilder;
        else
            window.BlobBuilder = function () {};
        if (window.webkitRequestFileSystem)
            window.requestFileSystem = webkitRequestFileSystem;
        else
            window.requestFileSystem = function () {};
    </script>
    <script src="js/Log.js"></script>
    <script src="js/Cpu.js"></script>
    <script src="js/CpuPdp11.js"></script>
    <script src="js/Memory.js"></script>
    <script src="js/MemoryUnibus.js"></script>
    <script src="js/DeviceMmu.js"></script>
    <script src="js/DeviceRk.js"></script>
    <script src="js/DeviceTt.js"></script>
    <script src="js/DeviceKw.js"></script>
    <script src="js/Pdp11.js"></script>
    <script src="term.js"></script>
</head>
<body>
    <!--pre>TODO:
* Remove browser dependant code into separated class.
* Physical/Virtual memory access dump.
* Interrupt priority.
* MUL/DIV detail implementation.
* Memory protection.
* Safari mobile support.
* Lots of unimplemented things...
==== CONSOLE ====</pre-->
    <script>
        pdp11_reset = function () {
            pdp11.cpu.init();
            pdp11.bootRk0();
            pdp11.memory.tt.set(new String("unix\n"));
            clearInterval(tid);
            tid = setInterval(pdp11_loop, 10);
        };
        pdp11_start = function() {
            clearInterval(tid);
            tid = setInterval(pdp11_loop, 10);
        };
        pdp11_stop = function () {
            clearInterval(tid);
            pdp11.stop();
        };
        pdp11_log = function () {
            pdp11_clear();
            Log.setLog(new Log("log", document.control.reversed.value));
            pdp11_select();
        };
        pdp11_select = function () {
            var level = [Log.INFO, Log.WARN, Log.ERROR, Log.FATAL];
            Log.getLog().setLevel(level[document.control.level.selectedIndex]);
        };
        pdp11_loop = function () {
            try {
                pdp11.run();
            } catch (e) {
                clearInterval(tid);
                Log.getLog().fatal(e);
            }
        };
        pdp11_clear = function () {
            Log.getLog().clear();
        };
        pdp11_mdump = function () {
            if (document.control.mdump.checked == true) {
                pdp11.cpu.logging = true;
                document.control.level.selectedIndex = 0;
                pdp11_select();
            } else {
                pdp11.cpu.logging = false;
            }
        };
        pdp11_rdump = function () {
            if (document.control.rdump.checked == true) {
                pdp11.logging = true;
                document.control.level.selectedIndex = 0;
                pdp11_select();
            } else {
                pdp11.logging = false;
            }
        };
        pdp11_rdump_now = function () {
            Log.getLog().setLevel(Log.INFO);
            pdp11.dump();
            pdp11_select();
            pdp11.memory.mmu.dump();
        };
        pdp11_cons = function () {
            pdp11.memory.tt.cons = document.control.cons.value;
        };
        pdp11_logto = function () {
            pdp11_clear();
            if (document.control.logtype[0].checked)
                pdp11_log();
            else if (document.control.logtype[1].checked) {
                var ws = new WebSocket("ws://localhost:8080/log");
                ws.writeLog = function (message) {
                    ws.send(message);
                };
                Log.setLog(new Log(ws));
            } else if (document.control.logtype[2].checked) {
                var bb = new BlobBuilder();
                bb.writeLog = function (message) {
                    bb.append(message);
                };
                Log.setLog(new Log(bb));
            } else {
                requestFileSystem(PERSISTENT, 1024 * 1024 * 1024, function (fs) {
                    fs.root.getFile("log.txt", { create: true }, function (file) {
                        file.createWriter(function (writer) {
                            var busy = false;
                            var bb = new BlobBuilder();
                            writer.onwrite = function (e) {
                                busy = false;
                                writer.flushLog();
                            };
                            writer.onerror = function (e) {
                                console.log(e);
                            };
                            writer.flushLog = function () {
                                if (busy)
                                    return;
                                var blob = bb.getBlob();
                                if (blob.size == 0)
                                    return;
                                busy = true;
                                bb = new BlobBuilder();
                                writer.write(blob);
                            };
                            writer.writeLog = function (message) {
                                bb.append(message);
                                writer.flushLog();
                            };
                            writer.truncate(0);
                            Log.setLog(new Log(writer));
                            pdp11_select();
                        });
                    });
                });
            }
            pdp11_select();
        };
        pdp11_blobdl = function () {
            var blob = Log.getLog().id.getBlob();
            var url = webkitURL.createObjectURL(blob);
            open(url, false);
        };
    </script>
    <pre id="term"
         style="background-color: black;
                color: green;
                display: inline-block;"></pre>
    <div style="font-family: monospace;"><form name="control">
        [PDP-11]
            <input type="button" value="RESET" onclick="pdp11_reset();">
            <input type="button" value="START" onclick="pdp11_start();">
            <input type="button" value="STOP" onclick="pdp11_stop();"><br>
        [LOG]
        REVERSED
            <input type="checkbox" name="reversed" checked="true"
                   onchange="pdp11_log();">
        LEVEL
            <select name="level" onchange="pdp11_select();">
            <option>INFO</option>
            <option>WARN</option>
            <option selected="selected">ERROR</option>
            <option>FATAL</option></select>
        REG DUMP
            <input type="checkbox" name="rdump" onchange="pdp11_rdump();">
            <input type="button" value="NOW" onclick="pdp11_rdump_now();">
        MEM DUMP
            <input type="checkbox" name="mdump" onchange="pdp11_mdump();">
            <input type="button" value="CLEAR" onclick="pdp11_clear();"><br>
        [CONSOLE]
            <input type="checkbox" name="cons" checked="true"
                   onchange="pdp11_cons();"><br>
        [DEBUG]
        Log to
            <input type="radio" name="logtype" onclick="pdp11_logto();"
                    checked="true">
            DOM
            <input type="radio" name="logtype" onclick="pdp11_logto();">
            ws://localhost:8080/log
            <input type="radio" name="logtype" onclick="pdp11_logto();">
            Blob
            <input type="button" value="Download" onclick="pdp11_blobdl();">
            <input type="radio" name="logtype" onclick="pdp11_logto();">
            File API
    </form></div>
    <pre>==== DEBUG LOG ====</pre>
    <pre id="log"></pre>
    <script>
        Log.setLog(new Log("log", true));
        Log.getLog().setLevel(Log.ERROR);
        var pdp11 = new Pdp11();
        var term = new Term("term", 80, 25);
        term.appendString("v6/js-11 booting from rk0 ...\n");
        pdp11.memory.tt.setCallback(function (c) { term.appendCharacter(c); });
        document.onkeypress = function (e) { pdp11.memory.tt.set(e.which); };
        pdp11.memory.tt.set(new String("unix\n"));  // Queue auto-boot console inputs
        pdp11.mountRk0("./data/v6root");
        pdp11.bootRk0();
        var tid = setInterval(pdp11_loop, 10);
    </script>
</body>
</html>
